package com.bang.daybreak.security.serivce.impl;

import com.bang.daybreak.common.framework.service.impl.BaseServiceImpl;
import com.bang.daybreak.security.model.SysUserDetails;
import com.bang.daybreak.user.mapper.SysUserMapper;
import com.bang.daybreak.user.model.entity.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 自定义实现类实现UserDetailsService
 * </p>
 *
 * @author wangdejian
 * @since 2019-08-10
 */
@Service
public class MyUserDetailsServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> implements UserDetailsService {

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 实现security UserDetailsService接口。
     * <p>
     * 授权的时候是对角色授权，而认证的时候应该基于资源，而不是角色，因为资源是不变的，而用户的角色是会变的
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        SysUserDetails sysUserDetails = new SysUserDetails();
        // 根据用户名获取到用户实体.
        SysUser sysUser = query().eq(SysUser::getUsername, username).eq(SysUser::getEnabled, 1).getOne();
        if (sysUser == null) {
            throw new UsernameNotFoundException("该用户不存在");
        }
        sysUserDetails.setSysUser(sysUser);
        Set authoritiesSet = new HashSet<>();

        // 根据sysUser获取到角色信息.
        List<String> codeList = sysUserMapper.selectUserMenuListByUserId(sysUser.getUserId());
        for (String code : codeList) {
            GrantedAuthority authority = new SimpleGrantedAuthority(code);
            authoritiesSet.add(authority);
        }
        sysUserDetails.setAuthorities(authoritiesSet);
        return sysUserDetails;
    }
}
